public class BuiltinFunctions {

	/**
	 * @param args
	 */
	public Sexpr car(Sexpr param) {
		if (param.isAtom != true) {
			param = param.car;
			if (param.isAtom != true) {
				param = param.car;
				return param;
			} else {
				System.err.println("Invalid parameter for car");
				return null;
			}
		}
		System.err.println("Invalid parameter for car");
		return null;
	}

	public Sexpr cdr(Sexpr param) {
		if (param.isAtom != true) {
			param = param.car;
			if (param.isAtom != true) {
				param = param.cdr;
				return param;
			} else {
				System.err.println("Invalid parameter for cdr");
				return null;
			}
		}
		System.err.println("Invalid parameter for cdr");
		return null;
	}

	public Sexpr cons(Sexpr param) {
		Sexpr ret = new Sexpr("NIL");
		Sexpr sexpr;
		if (param.isAtom != true) {
			if (param.cdr.isAtom != true) {
				ret.car = param.car;
				param = param.cdr;
				ret.cdr = param.car;
				ret.isAtom = false;
				return ret;
			}
		}
		System.err.println("Invalid parameter for cons");
		return null;
	}

	public Sexpr atom(Sexpr sexpr) {
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		if(sexpr.sexprLength(sexpr) > 1)
		{
			System.err.println("invalid parameter for Atom");
			return null;
		}
		T.isAtom = true;
		T.isID = false;
		T.isNumber = false;
		if (sexpr.car.isAtom != true)
		{
			return NIL;
		}
		else
			return T;		
	}
	public Sexpr intBuiltin(Sexpr sexpr) {
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		T.isAtom = true;
		T.isID = false;
		T.isNumber = false;
		if(sexpr.car.isNumber == true)
			return T;
		else 
			return NIL;		
	}
	public Sexpr eq(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		NIL.isAtom = true;
		NIL.isID = true;
		NIL.isNumber = false;
		NIL.isNIL = true;
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Eval eval = new Eval();
		T.isAtom = true;
		T.isID = true;
		T.isNumber = false;
		T.isNIL = false;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for eq: should be an atom-list with two elements");
			return null;			
		}
		ret = param.car;
		if((ret.isAtom != true)||(eval.getSexprType(ret) == TokenType.ID))
		{
			System.err.println("Invalid parameter for eq: The element in list should be atom");
			return null;
		}
		String a = ret.Value;
		param = param.cdr;
		ret = param.car;
		if((ret.isAtom != true)||(eval.getSexprType(ret) == TokenType.ID))
		{
			System.err.println("Invalid parameter for eq: The element in list should be atom");
			return null;
		}
		String b = ret.Value;
		if(a.equals(b) == true)
			return T;
		else
			return NIL;
	}
	public Sexpr Null(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for null");
			return null;
		}
		ret = param.car;
		if(ret.isNIL == true)
		{
			return T;			
		}
		return NIL;
	}
	public Sexpr plus(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Sexpr sexprNew = new Sexpr("NIL");
		int r = 0;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for null");
			return null;
		}
		else
		{
			r = Integer.parseInt(param.car.Value);
			r = r + Integer.parseInt(param.cdr.car.Value);
			sexprNew.Value= Integer.toString(r);
			sexprNew.isAtom = true;
			sexprNew.isNIL = false;
			sexprNew.isID = false;
			sexprNew.isNumber = true;
			ret = sexprNew;			
			return ret;
		}		
	}
	public Sexpr minus(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Sexpr sexprNew = new Sexpr("NIL");
		int r = 0;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for null");
			return null;
		}
		else
		{
			r = Integer.parseInt(param.car.Value);
			r = r - Integer.parseInt(param.cdr.car.Value);
			sexprNew.Value= Integer.toString(r);
			sexprNew.isAtom = true;
			sexprNew.isNIL = false;
			sexprNew.isID = false;
			sexprNew.isNumber = true;
			ret = sexprNew;			
			return ret;
		}		
	}
	public Sexpr greater(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		NIL.isAtom = true;
		NIL.isID = true;
		NIL.isNumber = false;
		NIL.isNIL = true;
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Eval eval = new Eval();
		T.isAtom = true;
		T.isID = true;
		T.isNumber = false;
		T.isNIL = false;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for eq: should be an atom-list with two elements");
			return null;			
		}
		ret = param.car;
		if((ret.isAtom != true)||(eval.getSexprType(ret) == TokenType.ID))
		{
			System.err.println("Invalid parameter for eq: The element in list should be atom");
			return null;
		}
		String a = ret.Value;
		param = param.cdr;
		ret = param.car;
		if((ret.isAtom != true)||(eval.getSexprType(ret) == TokenType.ID))
		{
			System.err.println("Invalid parameter for eq: The element in list should be atom");
			return null;
		}
		String b = ret.Value;
		if(Integer.parseInt(a) > Integer.parseInt(b))
//		if(a.equals(b) == true)
			return T;
		else
			return NIL;
	}
	public Sexpr less(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		NIL.isAtom = true;
		NIL.isID = true;
		NIL.isNumber = false;
		NIL.isNIL = true;
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Eval eval = new Eval();
		T.isAtom = true;
		T.isID = true;
		T.isNumber = false;
		T.isNIL = false;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for eq: should be an atom-list with two elements");
			return null;			
		}
		ret = param.car;
		if((ret.isAtom != true)||(eval.getSexprType(ret) == TokenType.ID))
		{
			System.err.println("Invalid parameter for eq: The element in list should be atom");
			return null;
		}
		String a = ret.Value;
		param = param.cdr;
		ret = param.car;
		if((ret.isAtom != true)||(eval.getSexprType(ret) == TokenType.ID))
		{
			System.err.println("Invalid parameter for eq: The element in list should be atom");
			return null;
		}
		String b = ret.Value;
		if(Integer.parseInt(a) < Integer.parseInt(b))
//		if(a.equals(b) == true)
			return T;
		else
			return NIL;
	}
	public Sexpr times(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Sexpr sexprNew = new Sexpr("NIL");
		int r = 0;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for null");
			return null;
		}
		else
		{
			r = Integer.parseInt(param.car.Value);
			r = r * Integer.parseInt(param.cdr.car.Value);
			sexprNew.Value= Integer.toString(r);
			sexprNew.isAtom = true;
			sexprNew.isNIL = false;
			sexprNew.isID = false;
			sexprNew.isNumber = true;
			ret = sexprNew;			
			return ret;
		}		
	}
	public Sexpr quotient(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Sexpr sexprNew = new Sexpr("NIL");
		int r = 0;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for null");
			return null;
		}
		else
		{
			r = Integer.parseInt(param.car.Value);
			r = r / Integer.parseInt(param.cdr.car.Value);
			sexprNew.Value= Integer.toString(r);
			sexprNew.isAtom = true;
			sexprNew.isNIL = false;
			sexprNew.isID = false;
			sexprNew.isNumber = true;
			ret = sexprNew;			
			return ret;
		}		
	}
	public Sexpr remainder(Sexpr param)
	{
		Sexpr NIL = new Sexpr("NIL");
		Sexpr T = new Sexpr("T");
		Sexpr ret = new Sexpr("NIL");
		Sexpr sexprNew = new Sexpr("NIL");
		int r = 0;
		if(param.isAtom == true)
		{
			System.err.println("Invalid parameter for null");
			return null;
		}
		else
		{
			r = Integer.parseInt(param.car.Value);
			r = r % Integer.parseInt(param.cdr.car.Value);
			sexprNew.Value= Integer.toString(r);
			sexprNew.isAtom = true;
			sexprNew.isNIL = false;
			sexprNew.isID = false;
			sexprNew.isNumber = true;
			ret = sexprNew;			
			return ret;
		}		
	}
	
	
	
	
	
	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
